import { IAbility, IContext, IParam, verifyNodeLinkCond, deepCopy, typeOf, UILogicParamService, UILogicParamType } from "@/core";
/**
 * 打开语雀文档
 * 基于template/src/ui-service/{{appEntities}}/{{uiLogics}}-ui-logic-base.ts.hbs生成  
 * @export
 * @class OpenYuQueUILogicBase
 */
export class OpenYuQueUILogicBase {

    /**
     * 返回结果
     *
     * @private
     * @type {*}
     * @memberof OpenYuQueUILogicBase
     */
    private result: any;

    /**
     * 行为附加参数
     *
     * @type {*}
     * @memberof OpenYuQueUILogicBase
     */
    public additionalParam: IParam = {};

    /**
     * 界面逻辑上下文
     *
     * @private
     * @type {IContext}
     * @memberof OpenYuQueUILogicBase
     */
    private appContext!: IContext;

    /**
     * 界面逻辑视图参数
     *
     * @private
     * @type {IParam}
     * @memberof OpenYuQueUILogicBase
     */
    private viewParam!: IParam;

    /**
     * 默认逻辑处理参数名称
     *
     * @private
     * @type {string}
     * @memberof OpenYuQueUILogicBase
     */
    private defaultParamName: string = '';

    /**
     * 应用上下文参数名称
     *
     * @private
     * @type {string}
     * @memberof OpenYuQueUILogicBase
     */
    private navContextParamName: string = '';

    /**
     * 视图参数名称
     *
     * @private
     * @type {string}
     * @memberof OpenYuQueUILogicBase
     */
    private navViewParamParamName: string = '';

    /**
     * 当前容器参数名称
     *
     * @private
     * @type {string}
     * @memberof OpenYuQueUILogicBase
     */
    private activeContainerParamName: string = '';

    /**
     * 当前激活部件参数名称
     *
     * @private
     * @type {string}
     * @memberof OpenYuQueUILogicBase
     */
    private activeCtrlParamName: string = '';

    /**
     * 当前激活视图对象名称
     *
     * @private
     * @type {string}
     * @memberof OpenYuQueUILogicBase
     */
    private activeViewParamName: string = '';

    /**
     * 上一次调用返回参数名称
     *
     * @private
     * @type {string}
     * @memberof OpenYuQueUILogicBase
     */
    private lastReturnParamName: string = '';

    /**
     * 逻辑参数Map
     *
     * @private
     * @type {Map<string, IParam>}
     * @memberof OpenYuQueUILogicBase
     */
    private logicParamMap: Map<string, IParam> = new Map();

    /**
     * 绑定上一次调用返回参数
     *
     * @memberof OpenYuQueUILogicBase
     */
    public bindLastReturnParam(value: any) {
        const lastReturnParam = this.logicParamMap.get(this.lastReturnParamName);
        if (lastReturnParam) {
            lastReturnParam.bind(value);
        }
    }

    /**
     * 默认逻辑处理参数
     *
     * @memberof OpenYuQueUILogicBase
     */
    get defaultParam(): any {
        return this.logicParamMap.get(this.defaultParamName);
    }

    /**
     * 上下文数据（包括应用上下文和逻辑局部上下文参数）
     *
     * @readonly
     * @memberof OpenYuQueUILogicBase
     */
    get context() {
        const navContextParam = this.logicParamMap.get(this.navContextParamName);
        if (navContextParam) {
            return navContextParam.getReal();
        } else {
            return this.appContext;
        }
    }

    /**
     * 视图参数数据（包括外部传入视图参数和逻辑局部视图参数）
     *
     * @readonly
     * @memberof OpenYuQueUILogicBase
     */
    get viewParams() {
        const navViewParamParam = this.logicParamMap.get(this.navViewParamParamName);
        if (navViewParamParam) {
            return navViewParamParam.getReal();
        } else {
            return this.viewParam;
        }
    }

    /**
     * 获取逻辑处理参数
     *
     * @param {string} key 逻辑处理参数的codeName
     * @memberof UIActionContext
     */
    private getParam(key: string): any {
        return this.logicParamMap.get(key);
    }

   	/**
     * Creates an instance of OpenYuQueUILogicBase
     * 
     * @param {IParam} [opts={}]
     * @memberof OpenYuQueUILogicBase
     */
    constructor(opts: IParam = {}) { }

    /**
     * 逻辑参数模型
     *
     * @private
     * @type {any[]}
     * @memberof OpenYuQueUILogicBase
     */
    private logicParamModels: any[] = [
        { 
            name: "传入变量", 
            codeName: "Default", 
            default: true, 
            entityParam: true,
        }
    ]

    /**
    * 初始化逻辑参数
    * @param context 应用上下文 
    * @param viewParams 视图参数
    * @param data 业务数据
    * @param event 事件对象
    * @param ability 当前环境能力
	* @memberof OpenYuQueUILogicBase
    */
    private initLogicParams<T extends IAbility>(context: IContext, viewParams: IParam, data: IParam, $event: MouseEvent, ability: T) {
        this.appContext = deepCopy(context);
        this.viewParam = deepCopy(viewParams);
        this.additionalParam = { data, $event, ctrl: ability.viewCtx.ctrl, actionContext: ability };
        this.logicParamModels.forEach((model: IParam) => {
            if (model.default) {
                this.defaultParamName = model.codeName;
            }
            if (model.navContextParam) {
                this.navContextParamName = model.codeName;
            }
            if (model.navViewParamParam) {
                this.navViewParamParamName = model.codeName;
            }
            if (model.activeContainerParam) {
                this.activeContainerParamName = model.codeName;
            }
            if (model.activeCtrlParam) {
                this.activeCtrlParamName = model.codeName;
            }
            if (model.activeViewParam) {
                this.activeViewParamName = model.codeName;
            }
            if (model.lastReturnParam) {
                this.lastReturnParamName = model.codeName;
            }
            const uiLogicParamInstance = UILogicParamService.getLogicParamInstance(this, model, { data, context, viewParams, $event, ctrl: ability.viewCtx.ctrl, actionContext: ability });
            this.logicParamMap.set(model.codeName, uiLogicParamInstance);
        });
    }

    /**
    * 执行界面逻辑之前
    * @param context 应用上下文 
    * @param viewParams 视图参数
    * @param data 业务数据
    * @param event 事件对象
    * @param ability 当前环境能力
	* @memberof OpenYuQueUILogicBase
    */
    private beforeExecute<T extends IAbility>(context: IContext, viewParams: IParam, data: IParam, event: MouseEvent, ability: T) {
        this.initLogicParams(context, viewParams, data, event, ability);
    }

    /**
    * 执行界面逻辑
    * @param context 应用上下文 
    * @param viewParams 视图参数
    * @param data 业务数据
    * @param event 事件对象
    * @param ability 当前环境能力
	* @memberof OpenYuQueUILogicBase
    */
    public async execute<T extends IAbility>(context: IContext, viewParams: IParam, data: IParam, event: MouseEvent, ability: T) {
        try {
            this.beforeExecute(context, viewParams, data, event, ability);
            await this.execute_Begin_node();
            return this.result;
        } catch (error: any) {
            throw new Error(`${error && error.message ? error.message : '发生未知错误！'}`);
        }
    }
    
    /**
     * 执行 开始 节点
     *
     * @protected
     * @memberof OpenYuQueUILogicBase
     */
    protected async execute_Begin_node() {
        this.result = this.defaultParam.getReal();
        console.log(`已完成执行 开始节点，操作参数数据如下:`);
        if (this.logicParamMap && (this.logicParamMap.size > 0)) {
            for (let [key, value] of this.logicParamMap) {
                console.log(key, deepCopy(value.getReal()));
            }
        }
        console.log(`即将执行界面行为节点`);
        await this.execute_DEUIACTION1_node();
    }
    
    /**
     * 执行 界面行为 节点
     *
     * @protected
     * @memberof OpenYuQueUILogicBase
     */
    protected async execute_DEUIACTION1_node() {
        try {
            const data = this.getParam("Default").getReal();
            const { $event, actionContext } = this.additionalParam;
            const uiService = await App.getUIService("IBIZOrder", this.context);
            if (uiService && uiService.open_document && uiService.open_document instanceof Function) {
                const result = await uiService.open_document(this.context, this.viewParams, Array.isArray(data) ? data : [data], $event, actionContext);
                if (result.ok) {
                    this.bindLastReturnParam(result.data);
                }
            }
            console.log(`已完成执行 界面行为节点，操作参数数据如下:`);
            if (this.logicParamMap && (this.logicParamMap.size > 0)) {
                for (let [key, value] of this.logicParamMap) {
                    console.log(key, deepCopy(value.getReal()));
                }
            }
            console.log(`即将执行结束节点`);
            await this.execute_END1_node();
        } catch (error: any) {
            throw new Error(`执行 界面行为 节点 ${error && error.message ? error.message : '发生未知错误！'}`);
        }
    }
    
    /**
     * 执行 结束 节点
     *
     * @protected
     * @memberof OpenYuQueUILogicBase
     */
    protected async execute_END1_node() {
    }

}
